package study.https.auth.sign;

import sun.misc.BASE64Decoder;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class SignUtil {

    private String keyFile;
    private String alogrithm;

    public SignUtil(){}
    public SignUtil(String keyFile,String alogrithm){
        this.keyFile = keyFile;
        this.alogrithm = alogrithm;
    }
    /**
     * 从密钥文件中加载私钥
     * @param filename
     * @param algorithm
     * @return
     * @throws Exception
     */
    public PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
        File f = new File(filename);
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int) f.length()];
        dis.readFully(keyBytes);
        dis.close();

        String temp = new String(keyBytes);
        String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");
        privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
        privKeyPEM = privKeyPEM.replace("\n", "");
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] decoded = decoder.decodeBuffer(privKeyPEM);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory kf = KeyFactory.getInstance(algorithm);
        return kf.generatePrivate(spec);
    }

    /**
     * 使用 alogirthm 算法对 data 进行签名
     * @param data
     * @return  签名后 base64 数据
     */
    public String sign(String data) {
        String signString = null;
        try {
            Signature signature = Signature.getInstance("SHA256withECDSA");
            PrivateKey privateKey = getPemPrivateKey(keyFile,alogrithm);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] result = signature.sign();
            signString = Base64.getEncoder().encodeToString(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return signString;
    }
}
